package principal;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;

import peca.Bispo;
import peca.Cavalo;
import peca.CorPeca;
import peca.Peao;
import peca.Rainha;
import peca.Rei;
import peca.Torre;
import util.PecaService;
import util.Relatorio;
import util.Selecionador;
import estrutura.Celula;
import estrutura.Peca;


public class Tabuleiro extends javax.swing.JPanel implements  ActionListener {
	private static final long serialVersionUID = -5628032735772175339L;
	private static final int LARGURA_ALTURA = 70;
	private JLabel jLabel2;
	private JLabel jLabel3;
	private JLabel destino;
	private JLabel peca;
	private Celula selecionado;
	private Celula[][] celulas;
	private CorPeca jogada;
	private boolean robo;
	private boolean xequePreto = false;
	private boolean xequeBranco = false;
	

	/**
	* Auto-generated main method to display this 
	* JPanel inside a new JFrame.
	*/
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		Tabuleiro tabuleiro =  new Tabuleiro(true); 
		frame.getContentPane().add(tabuleiro);
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
		//Console.inicio(tabuleiro,CorPeca.BRANCA);
		//Console.inicio(tabuleiro,CorPeca.PRETA);
	}
	
	public Tabuleiro(boolean robo) {
		super();
		initGUI();
		this.robo = robo;
	}
	
	private void initGUI() {
		try {
			this.celulas = new Celula[8][8];
			this.setPreferredSize(new java.awt.Dimension(816, 568));
			this.setLayout(null);
			{
				jLabel2 = new JLabel();
				this.add(jLabel2);
				jLabel2.setText("Selecionado:");
				jLabel2.setBounds(609, 12, 67, 16);
			}
			{
				jLabel3 = new JLabel();
				this.add(jLabel3);
				jLabel3.setText("Destino:");
				jLabel3.setBounds(609, 40, 67, 16);
			}
			{
				peca = new JLabel();
				this.add(peca);
				peca.setText("-");
				peca.setBounds(688, 12, 52, 16);
			}
			{
				destino = new JLabel();
				this.add(destino);
				destino.setText("-");
				destino.setBounds(688, 40, 52, 16);
			}

			{
				criarTabuleiro();
				iniciarPecas();
				setJogou(CorPeca.PRETA);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void setJogou(CorPeca cor) {
		if(cor == CorPeca.BRANCA){
			jogada = CorPeca.PRETA;
		}else{
			jogada = CorPeca.BRANCA;
		}
		
		
	}
	
	private CorPeca getProximoAJogar(){
		return jogada;
	}

	private void criarTabuleiro() {
		for (int x = 0; x < 8; x++) {
			int linha = x * LARGURA_ALTURA;
			for (int y = 0; y < 8; y++) {
				int coluna = y * LARGURA_ALTURA;
				Celula celula = new Celula(x,y);
				celula.setBackground((x+y)%2 == 0 ? new java.awt.Color(255,255,255) : new java.awt.Color(192,224,255));
				this.add(celula);
				celulas[x][y] = celula;
				celula.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
				celula.setBounds(coluna, linha, LARGURA_ALTURA, LARGURA_ALTURA);
				celula.addActionListener(this);
				celula.setName(String.valueOf(x)+String.valueOf(y));
				celula.setText(String.valueOf(x)+String.valueOf(y));
			}
		}
	}
	
	private void iniciarPecas(){
		posicionarPecas(CorPeca.PRETA);
		posicionarPecas(CorPeca.BRANCA);
	}

	private void posicionarPecas(CorPeca corPeca) {
		int i = corPeca == CorPeca.PRETA ? 0 : 7;
		int ii = corPeca == CorPeca.PRETA ? 1 : 6;
		celulas[i][0].setPeca(new Torre(corPeca));
		celulas[i][1].setPeca(new Cavalo(corPeca));
		celulas[i][2].setPeca(new Bispo(corPeca));
		celulas[i][3].setPeca(new Rainha(corPeca));
		celulas[i][4].setPeca(new Rei(corPeca));
		celulas[i][5].setPeca(new Bispo(corPeca));
		celulas[i][6].setPeca(new Cavalo(corPeca));
		celulas[i][7].setPeca(new Torre(corPeca));		
		for(int x = 0 ; x< 8 ; x++ ){
			celulas[ii][x].setPeca(new Peao(corPeca));
		}
	}


	@Override
	public void actionPerformed(ActionEvent event) {
		Celula evento = (Celula)event.getSource();
		jogar(evento);
	}

	public Celula[][] jogar(Celula evento) {
		if(isSelecionarPeca()){
			selecionarPeca(evento);
			return null;
		}
		else if(isDestinoMesmaOrigem(evento)){
			Selecionador.desfazerJogadasPossiveis(celulas);
			selecionado = null;
			peca.setText("-");
			return null;
		}
		
		if(isMovimentoInvalido(evento)){
			Selecionador.desfazerJogadasPossiveis(celulas);
			selecionado = null;
			peca.setText("-");
			return null;
		}
		
		if(evento.getPeca()!=null && (selecionado.getPeca().getCor() == evento.getPeca().getCor())){
			Selecionador.desfazerJogadasPossiveis(celulas);
			return null;
		}
		Peca rainha = viraRainha(selecionado,evento);
		if(rainha != null){
			evento.setPeca(rainha);
		}else{
			evento.setPeca(selecionado.getPeca());
		}
		
	
		destino.setText(evento.getName());
		selecionado.setIcon(null);
		selecionado.setPeca(null);
		Selecionador.desfazerJogadasPossiveis(celulas);
		setJogou(evento.getPeca().getCor());
		
		xequePreto = false;
		xequeBranco = false;
		
		if(isXeque(CorPeca.BRANCA) && robo){
			alert("XEQUE REI PRETO");
			xequePreto = true;
		}
		if(isXeque(CorPeca.PRETA) && robo){
			alert("XEQUE REI BRANCO");
			xequeBranco = true;
		}
		
		if(getProximoAJogar() == CorPeca.PRETA && robo){
			String jogada = Simulador.retornaMelhor(this, CorPeca.PRETA);
			Console c = new Console(this, CorPeca.PRETA);
			c.jogar(jogada);
		}
		
		return getCelulas();
		
	}

	private boolean isXeque(CorPeca cor) {
		if(robo){
			return Relatorio.xeque(cor, celulas);
		}
		return false;
		
	}

	private void alert(String string) {
		JOptionPane.showMessageDialog(this, string);
		
	}

	private boolean isMovimentoInvalido(Celula evento) {
		if(xequeBranco && selecionado.getPeca().getCor() == CorPeca.BRANCA && !selecionado.getPeca().getNome().equals(Peca.REI_B)){
			return false;
		}
		if(xequePreto && selecionado.getPeca().getCor() == CorPeca.PRETA &&  !selecionado.getPeca().getNome().equals(Peca.REI_P)){
			return false;
		}
		
		
		return !selecionado.getPeca().isMovimentoValido(selecionado, evento,celulas);		
	}

	private boolean isDestinoMesmaOrigem(Celula evento) {
		return selecionado.getName().equals(evento.getName());
	}

	private void selecionarPeca(Celula evento) {		
		if(evento.getPeca()==null){
			return;
		}
		if(evento.getPeca().getCor() != getProximoAJogar() && robo){
			alert( "Deve jogar "+getProximoAJogar());
			return;
		}
		selecionado = evento;
		peca.setText(evento.getName());
		destino.setText("-");
		Selecionador.selecionarJogadasPossiveis(selecionado, celulas);
	}

	private boolean isSelecionarPeca() {
		return selecionado == null || !destino.getText().equals("-");
	}
	
	private Peca viraRainha(Celula origem, Celula destino) {
		if(PecaService.ultimaLinha(destino.getText()) && origem.getPeca() instanceof Peao){
			return new Rainha(origem.getPeca().getCor());
		}
		return null;
	}		
	
	public Celula[][] getCelulas() {
		return celulas;
	}

	public void setRobo(boolean robo) {
		this.robo = robo;
	}

	public boolean isRobo() {
		return robo;
	}

	public void setCelulas(Celula[][] celulas2) {
		for (int x = 0; x < 8; x++) {
			for (int y = 0; y < 8; y++) {				
					celulas[x][y].setPeca(celulas2[x][y].getPeca());
			}
		}
	}
}
